package data;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;

public class RowDataGateway
{
	private String name;
	private boolean done;
	private Date dueDate;
	private String type;
	private String repeat;
	private ArrayList<RowDataGateway> childTasks;

	public RowDataGateway(String name, Date dueDate, String type, boolean done,
	    String rep, ArrayList<RowDataGateway> childTasks)
	{
		this.name = name;
		this.done = done;
		this.dueDate = dueDate;
		this.repeat = rep;
		this.type = type;
		this.childTasks = childTasks;
	}

	/**
	 * Need a defaul constructed in order to actually be able to read from the
	 * table without creating tasks.
	 */
	public RowDataGateway()
	{

	}

	/**
	 * Write THIS Row Data Gateway to The Database, and if possible, its
	 * childrens.
	 */
	public void insert()
	{
		String insertstatementstring = 
				"INSERT INTO " 
				+ "Task"
				+ " (taskname,taskdate,taskdone,taskfreq,tasktype) " 
				+ "values (?,?,?,?,?);";
		
		String insertchildrelations = 
				"INSERT INTO " 
				+ " ChildOf  "
				+ " (taskname,childtask) "
				+ " values (?,?); ";
		
		try
		{
			DBRegistry instance = DBRegistry.createInstance();
			instance.openDBConnection();
			checkIfTableExists(instance);

			PreparedStatement state = DBRegistry.createInstance()
			    .getDBConnection().prepareStatement(insertstatementstring);

			System.out.println(insertstatementstring);
			
			/* The meaty part. You're preparing, and then executing the batch. */
			state.setString(1, this.name);
			state.setDate(2, new java.sql.Date( this.dueDate.getTime()));
			state.setInt(3, this.done ? 1 : 0);
			state.setString(4, this.repeat);
			state.setString(5, this.type);
			state.addBatch();
			state.executeBatch();
			

			/* So we have added the root. Now to check if there's children ? add : donothing. */
			if (null != childTasks)
			{
				state = DBRegistry.createInstance()
				    .getDBConnection().prepareStatement(insertchildrelations);
				for (RowDataGateway abc : childTasks)
				{
					/* The meaty part. You're preparing, and then executing the batch. */
					state.setString(1, this.name);
					state.setString(2, abc.name);
					state.addBatch();
					state.executeBatch();
				}
			}
			
			instance.closeDBConnection();
		}

		catch (Exception e)
		{
			
		}
	}

	/**
	 * Update the row in TASK table.
	 */
	public void update()
	{
		try
		{
			DBRegistry instance = DBRegistry.createInstance();
			instance.openDBConnection();
			checkIfTableExists(instance);
			
			if(childTasks.size()==0)
			{
				instance.execute("UPDATE " + "Tasks" + 
						" SET taskdate="+this.dueDate.toString()+", " +
						" taskdone="+this.done+" " + 
						" WHERE taskname="+this.name+"");
				instance.closeDBConnection();
			}
			
			else if (childTasks.size()>0)
			{
				//we need to insert the task and also make sure its children are also inserted.
				instance.closeDBConnection();
			}
		}
		
		
		
		catch(Exception e)
		{
		
		}	
	}

	/**
	 * Return a Row Data Gateway with current info.
	 * 
	 * @return
	 */
	public RowDataGateway find()
	{
		return null;// -- returns a RDG object (usually static)
	}

	/** 
	 * This should read the tables and build the datastructure
	 * The data structure should then be analyzed and converted 
	 * to a proper model.
	 */
	public ArrayList<RowDataGateway> findAll()
	{
		ArrayList<RowDataGateway> rdg = new ArrayList<RowDataGateway>();
		RowDataGateway tmp; 
		ResultSet rset; 
		String db_taskname;
		String db_taskchildname;
		String db_freq; 
		String db_type;
		Date db_date; 
		boolean db_done; 
		
		/* First acquire all standard tasks */
		
		checkIfTableExists(DBRegistry.createInstance()); 
		
		rset = DBRegistry.createInstance().execute("SELECT * FROM " + "Task" + ";");
		
		try
		{
			
			while(rset.next())
			{
				db_taskname = rset.getString("taskname");
				db_date = rset.getDate("taskdate");
				db_done = rset.getInt("taskdone") == 1 ? true : false;
				db_freq = rset.getString("taskfreq"); 
				db_type = rset.getString("tasktype"); 
				
				tmp = new RowDataGateway(
						db_taskname
						,db_date
						,db_type
						,db_done
						,db_freq
						,null);
				
				rdg.add(tmp);
						
			}
		}
		catch(Exception e)
		{
			
		}
		
		/* Second all nested tasks */
		rset = DBRegistry.createInstance().execute("SELECT * FROM " + "ChildOf" + ";");
		
		try
		{
			while(rset.next())
			{
				/* Find the relation */
				db_taskname = rset.getString("taskname");
				db_taskchildname = rset.getString("childtask");
				
				/* Search it in the loop of the whole cluster, and assign it properly */
				
				
			}
		}
		catch(Exception e)
		{
			
		}
		
		return rdg;
	}

	/**
	 * Delete The row from the Task Table. 
	 */
	public void delete()
	{				
		try
		{
			DBRegistry instance = DBRegistry.createInstance();
			instance.openDBConnection();
			checkIfTableExists(instance);
			
			/* 
			 * Since using foreign keys, this will take care of removing
			 * tasks from the children table 
			 */
			
			instance.execute(" DELETE FROM " + "Tasks" +  " WHERE taskname="+this.name+";");
			instance.closeDBConnection();
		}
		
		catch(Exception e)
		{
		
		}		
	}
	
	/*
	 * main schema declaration / creation 
	 */
	private void checkIfTableExists(DBRegistry instance)
	{		
		String createTaskTable = new String(
		"CREATE TABLE IF NOT EXISTS " + "Task" + " ( " + 
		" taskname VARCHAR(50) PRIMARY KEY " +
		" ,taskdate DATETIME " + 
		" ,taskdone INTEGER " +
  	" ,taskfreq VARCHAR(50) " +
		" ,tasktype VARCHAR(50) " + 
		" ); "
		);
				
		String createRelationChildOf = new String(
		"CREATE TABLE IF NOT EXISTS " + "ChildOf" + " ( " + 
		" taskname VARCHAR(50)" +
		" ,childtask VARHCHAR(50) " + ", " +  
		" FOREIGN KEY(taskname) REFERENCES Tasks(taskname)"+
		" FOREIGN KEY(childTask) REFERENCES Tasks(taskname)"+
		" ); "
		);
				
		instance.exupdate(createTaskTable);
		instance.exupdate(createRelationChildOf);			
	}
	   
	public String getName() 
	{
		return name;
	}	
    
	public void setName(String name) 
	{
		this.name = name;
	}    

	public boolean isDone() 
	{
		return done;
	}
    
	public void setDone(boolean done) 
	{
		this.done = done;
	}
    
	public Date getDueDate() 
	{
		return dueDate;
	}

	public void setDueDate(Date dueDate) 
	{
		this.dueDate = dueDate;
	}

	public String getType() 
	{
		return type;
	}

	public void setType(String type) 
	{
		this.type = type;
	}
	
	public void setmTodo(ArrayList<RowDataGateway> childTasks) 
	{
		this.childTasks = childTasks;
	}
	
	/** 
	 * In order to return a reference to the 
	 * children, for later adding from complex tasks
	 * @return
	 */
	public ArrayList<RowDataGateway> getChildren()
	{
		return childTasks; 
	}

	/**
	 * Set the frequency if the task is periodic
	 * @param str
	 */
	public void setFrequency(String str)
	{
		repeat = str; 
	}
	
	/** TODO
	 * Needed for nesting
	 * 
	 * I can't store the frequency.
	 * 
	 * @param name2
	 * @param dueDate2
	 * @param type2
	 */
	public void addSubtask(String name2, Date dueDate2, String type2)
  {
		childTasks.add(new RowDataGateway(name2, dueDate2, type2, false, null, null)); 
  }
	
}
